home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr46 / vfwdk.zip / VFWSDK.ZIP / SAMPLES / MOVPLAY / MOVPLAY2.C < prev   
C/C++ Source or Header  |  1993-01-27  |  17KB  |  534 lines

  1. /*--------------------------------------------------------------------
  2. |
  3. | MovPlay.c - Sample Win app to play AVI movies using mciSendString
  4. |
  5. | Movie Functions supported:
  6. |    Play/Pause
  7. |    Home/End
  8. |    Step/ReverseStep
  9. |
  10. |   Copyright (c) 1992, 1993 Microsoft Corporation.  All Rights Reserved.
  11. |
  12. |    You have a royalty-free right to use, modify, reproduce and 
  13. |    distribute the Sample Files (and/or any modified version) in 
  14. |    any way you find useful, provided that you agree that 
  15. |    Microsoft has no warranty obligations or liability for any 
  16. |    Sample Application Files.
  17. |
  18. +--------------------------------------------------------------------*/
  19. #include <windows.h>
  20. #include <commdlg.h>
  21. #include <string.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <direct.h>
  25. #include <mmsystem.h>        
  26. #include <digitalv.h>        
  27. #include "movplay.h"
  28.  
  29.  
  30. /* function declarations */
  31. long FAR PASCAL _export WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  32. void fileCloseMovie(HWND hWnd);
  33. void fileOpenMovie(HWND hWnd);
  34. void positionMovie(HWND hWnd);
  35. void playMovie(HWND hWnd, WORD wDirection);
  36. void seekMovie(HWND hWnd, WORD wAction);
  37. void stepMovie(HWND hWnd, WORD wDirection);
  38. void menubarUpdate(HWND hWnd);
  39. void titlebarUpdate(HWND hWnd, LPSTR lpstrMovie);
  40.  
  41.  
  42. /**************************************************************
  43. ************************ GLOBALS ******************************
  44. **************************************************************/
  45. /* AVI stuff to keep around */
  46. WORD wMCIDeviceID = 0;    /* MCI Device ID for the AVI file */
  47. HWND hwndMovie;        /* window handle of the movie */
  48. RECT rcMovie;        /* the rect where the movie is positioned      */
  49.             /* for QT/W this is the movie rect, for AVI    */
  50.             /* this is the location of the playback window */
  51. BOOL fPlaying = FALSE;    /* Play flag: TRUE == playing, FALSE == paused */
  52. BOOL fMovieOpen = FALSE;/* Open flag: TRUE == movie open, FALSE = none */
  53. HANDLE hAccel = NULL;    /* accelerator table */
  54. HMENU hMenuBar = NULL;    /* menu bar handle */
  55. char szAppName [] = "MovPlay";
  56.  
  57. /********************************************************************
  58. ************************** FUNCTIONS ********************************
  59. ********************************************************************/
  60. /*--------------------------------------------------------------+
  61. | initAVI - initialize avi libraries                |
  62. |                                |
  63. +--------------------------------------------------------------*/
  64. BOOL initAVI(void)
  65. {
  66.     return mciSendString("open avivideo", NULL, 0, NULL) == 0;
  67. }
  68.  
  69. void termAVI(void)
  70. {
  71.     mciSendString("close avivideo", NULL, 0, NULL);
  72. }
  73.  
  74. /*--------------------------------------------------------------+
  75. | initApp - initialize the app overall.                |
  76. |                                |
  77. | Returns the Window handle for the app on success, NULL if    |
  78. | there is a failure.                        |
  79. |                                |
  80. +--------------------------------------------------------------*/
  81. HWND initApp(HINSTANCE hInstance, HINSTANCE hPrevInstance, int nCmdShow)
  82. {
  83.    HWND        hWnd;    /* window handle to return */
  84.    
  85.    if (!hPrevInstance){
  86.       WNDCLASS    wndclass; 
  87.       
  88.       wndclass.style         = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  89.       wndclass.lpfnWndProc   = WndProc;
  90.       wndclass.cbClsExtra    = 0;
  91.       wndclass.cbWndExtra    = 0;
  92.       wndclass.hInstance     = hInstance;
  93.       wndclass.hIcon         = LoadIcon (hInstance, "AppIcon");
  94.       wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  95.       wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  96.       wndclass.lpszMenuName  = szAppName;
  97.       wndclass.lpszClassName = szAppName;
  98.  
  99.       if (!RegisterClass(&wndclass)){
  100.          MessageBox(NULL, "RegisterClass failure", szAppName, MB_OK);
  101.          return NULL;
  102.       }
  103.    }
  104.  
  105.    /* create the main window for the app */
  106.    hWnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW |
  107.       WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  108.       CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  109.  
  110.    if (hWnd == NULL){
  111.       MessageBox(NULL, "CreateWindow failure", szAppName, MB_OK);
  112.       return NULL;
  113.    }
  114.  
  115.    hMenuBar = GetMenu(hWnd);    /* get the menu bar handle */
  116.    menubarUpdate(hWnd);        /* update menu bar to disable Movie menu */
  117.    
  118.    /* Show the main window */
  119.    ShowWindow(hWnd, nCmdShow);
  120.    UpdateWindow(hWnd);
  121.  
  122.    /* load the accelerator table */
  123.    hAccel = LoadAccelerators(hInstance, szAppName);
  124.    
  125.    return hWnd;
  126. }
  127.  
  128.  
  129. /*--------------------------------------------------------------+
  130. | WinMain - main routine.                    |
  131. |                                |
  132. +--------------------------------------------------------------*/
  133. int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  134.                 LPSTR lpszCmdParam, int nCmdShow)
  135. {
  136.    HWND        hWnd;
  137.    MSG         msg;
  138.  
  139.    if (!initAVI())
  140.        return 0;
  141.        
  142.    if ((hWnd = initApp(hInstance, hPrevInstance,nCmdShow)) == NULL)
  143.        return 0;    /* died initializing, bail out */
  144.  
  145.    /* main message loop, be sure to handle accelerators */
  146.    while (GetMessage(&msg, NULL, 0, 0)){
  147.       if (!TranslateAccelerator(hWnd, hAccel, &msg)) {
  148.           TranslateMessage(&msg);
  149.           DispatchMessage(&msg);
  150.       }
  151.    }
  152.  
  153.    return msg.wParam;
  154. }
  155.  
  156.  
  157. /*--------------------------------------------------------------+
  158. | WndProc - window proc for the app                |
  159. |                                |
  160. +--------------------------------------------------------------*/
  161. long FAR PASCAL _export WndProc (HWND hWnd, UINT message, WPARAM wParam,
  162.                         LPARAM lParam)
  163. {
  164.    PAINTSTRUCT ps;
  165.    WORD w;
  166.    WORD    wMenu;
  167.  
  168.    switch (message){
  169.         case WM_CREATE:
  170.         return 0;
  171.  
  172.     case WM_INITMENUPOPUP:
  173.         /* be sure this isn't the system menu */
  174.         if (HIWORD(lParam))
  175.             return DefWindowProc(hWnd, WM_INITMENUPOPUP, 
  176.                         wParam, lParam);
  177.   
  178.         wMenu = LOWORD(lParam);
  179.         switch (wMenu){
  180.             case 0:   /* file menu */
  181.                 /* turn on/off CLOSE & PLAY */
  182.                 if (fMovieOpen) w = MF_ENABLED|MF_BYCOMMAND;
  183.                 else        w = MF_GRAYED|MF_BYCOMMAND;
  184.                 EnableMenuItem((HMENU)wParam, IDM_CLOSE, w);
  185.                 break;
  186.                 
  187.             case 1:    /* Movie menu */
  188.                 /* check or uncheck the PLAY menu item */
  189.                 if (fPlaying)  w = MF_CHECKED|MF_BYCOMMAND;
  190.                 else           w = MF_UNCHECKED|MF_BYCOMMAND;
  191.                 CheckMenuItem((HMENU)wParam, IDM_PLAY, w);
  192.                 break;
  193.         } /* switch */
  194.         break;
  195.         
  196.     case WM_COMMAND:
  197.         /* handle the menu commands */
  198.         switch (wParam) {
  199.             /* File Menu */
  200.             case IDM_OPEN:
  201.                 fileOpenMovie(hWnd);
  202.                 break;
  203.             case IDM_CLOSE:
  204.                 fileCloseMovie(hWnd);
  205.                 break;
  206.             case IDM_EXIT:
  207.                 PostMessage(hWnd, WM_CLOSE, 0, 0L);
  208.                 break;
  209.             case IDM_ANOTHER:
  210.                 /* just fork another MovPlay */
  211.                 WinExec((LPSTR)szAppName, SW_SHOW);
  212.                 break;
  213.                 
  214.             /* Movie Menu - note some of these are by */
  215.             /* keyboard only, especially the REVERSE  */
  216.             /* commands.                  */
  217.             case IDM_PLAY:
  218.             case IDM_RPLAY:
  219.                 playMovie(hWnd, wParam);
  220.                 break;
  221.             case IDM_HOME:
  222.             case IDM_END:
  223.                 seekMovie(hWnd, wParam);
  224.                 break;
  225.             case IDM_STEP:
  226.             case IDM_RSTEP:
  227.                 stepMovie(hWnd,wParam);
  228.                 break;
  229.         }
  230.         return 0;
  231.  
  232.     case WM_SIZE:
  233.         positionMovie(hWnd);    /* re-center the movie */
  234.         return 0;
  235.         
  236.         case WM_PAINT:
  237.         if (!BeginPaint(hWnd, &ps))
  238.             return 0;
  239.         EndPaint(hWnd, &ps);
  240.         return 0;
  241.  
  242.     case WM_DESTROY:
  243.         if (fMovieOpen)
  244.             fileCloseMovie(hWnd);
  245.         termAVI();
  246.         PostQuitMessage(0);
  247.         return 0;
  248.         
  249.     case MM_MCINOTIFY:
  250.         /* This is where we check the status of an AVI    */
  251.         /* movie that might have been playing.  We do    */
  252.         /* the play with MCI_NOTIFY on so we should get    */
  253.         /* a MCI_NOTIFY_SUCCESSFUL if the play        */
  254.         /* completes on it's own.            */
  255.         switch(wParam){
  256.             case MCI_NOTIFY_SUCCESSFUL:
  257.                 /* the play finished, let's rewind */
  258.                 /* and clear our flag.           */
  259.                 fPlaying = FALSE;
  260.                 mciSendString("seek mov to start", NULL, 0,
  261.                         NULL);
  262.                 return 0;
  263.         }
  264.      
  265.    } /* switch */
  266.    return DefWindowProc(hWnd, message, wParam, lParam);
  267. }
  268.  
  269. /*--------------------------------------------------------------+
  270. | menubarUpdate - update the menu bar based on the <fMovieOpen> |
  271. |          flag value.  This will turn on/off the    |
  272. |          Movie menu.                    |
  273. |                                |
  274. +--------------------------------------------------------------*/
  275. void menubarUpdate(HWND hWnd)
  276. {
  277.    WORD w;
  278.    
  279.    if (fMovieOpen){
  280.        w = MF_ENABLED|MF_BYPOSITION;
  281.    } else {
  282.        w = MF_GRAYED|MF_BYPOSITION;
  283.    }
  284.    EnableMenuItem(hMenuBar, 1, w);    /* change the Movie menu (#1) */
  285.    DrawMenuBar(hWnd);    /* re-draw the menu bar */
  286. }
  287.  
  288. /*--------------------------------------------------------------+
  289. | titlebarUpdate - update the title bar to include the name    |
  290. |           of the movie playing.            |
  291. |                                |
  292. +--------------------------------------------------------------*/
  293. void titlebarUpdate(HWND hWnd, LPSTR lpstrMovie)
  294. {
  295.    char achNewTitle[BUFFER_LENGTH];    // space for the title 
  296.    
  297.    if (lpstrMovie != NULL)
  298.        wsprintf((LPSTR)achNewTitle,"%s - %s", (LPSTR)szAppName,lpstrMovie);
  299.    else
  300.        lstrcpy((LPSTR)achNewTitle, (LPSTR)szAppName);
  301.    SetWindowText(hWnd, (LPSTR)achNewTitle);
  302. }
  303.  
  304. /*--------------------------------------------------------------+ 
  305. | positionMovie - sets the movie rectange <rcMovie> to be    |
  306. |        centered within the app's window.        |
  307. |                                |
  308. +--------------------------------------------------------------*/
  309. VOID positionMovie(HWND hWnd)
  310. {
  311.    RECT    rcClient;
  312.    RECT rcMovieBounds;
  313.    char    achRect[128];
  314.    char *p;
  315.    
  316.    /* if there is no movie yet then just get out of here */
  317.    if (!fMovieOpen)
  318.        return;
  319.    
  320.    GetClientRect(hWnd, &rcClient);    /* get the parent windows rect */
  321.        
  322.    /* get the original size of the movie */
  323.    mciSendString("where mov source", (LPSTR)achRect, sizeof(achRect), NULL);
  324.    
  325.    SetRectEmpty(&rcMovieBounds);    // zero out movie rect
  326.    p = achRect;    // point to rectangle string returned by where command 
  327.    while (*p == ' ') p++;    // skip over starting spaces
  328.    while (*p != ' ') p++;    // skip over the x (which is 0) 
  329.    while (*p == ' ') p++;    // skip over spaces between x and y
  330.    while (*p != ' ') p++;    // skip over the y (which is 0)
  331.    while (*p == ' ') p++;    // skip over the spaces between y and width
  332.        
  333.    /* now find the width */
  334.    for (; *p >= '0' && *p <= '9'; p++)
  335.        rcMovieBounds.right = (10 * rcMovieBounds.right) + (*p - '0');
  336.    while (*p == ' ') p++;    // skip spaces between width and height
  337.    
  338.    /* now find the height */
  339.    for (; *p >= '0' && *p <= '9'; p++)
  340.        rcMovieBounds.bottom = (10 * rcMovieBounds.bottom) + (*p - '0');
  341.  
  342.    /* figure out where to position the window at */
  343.    rcMovie.left = (rcClient.right/2) - (rcMovieBounds.right / 2);
  344.    rcMovie.top = (rcClient.bottom/2) - (rcMovieBounds.bottom / 2);
  345.    rcMovie.right = rcMovie.left + rcMovieBounds.right;
  346.    rcMovie.bottom = rcMovie.top + rcMovieBounds.bottom;
  347.    
  348.    /* reposition the playback (child) window */
  349.    MoveWindow(hwndMovie, rcMovie.left, rcMovie.top,
  350.        rcMovieBounds.right, rcMovieBounds.bottom, TRUE);
  351. }
  352.  
  353. /*--------------------------------------------------------------+ 
  354. | fileCloseMovie - close the movie and anything associated    |
  355. |           with it.                    |
  356. |                                |
  357. | This function clears the <fPlaying> and <fMovieOpen> flags    |
  358. |                                |
  359. +--------------------------------------------------------------*/
  360. void fileCloseMovie(HWND hWnd)
  361. {
  362.   mciSendString("close mov", NULL, 0, NULL);
  363.  
  364.   fPlaying = FALSE;    // can't be playing any longer
  365.   fMovieOpen = FALSE;    // no more movies open
  366.        
  367.   titlebarUpdate(hWnd, NULL);    // title bar back to plain
  368.   menubarUpdate(hWnd);        // update menu bar
  369.        
  370.   /* cause a total repaint to occur */
  371.   InvalidateRect(hWnd, NULL, TRUE);
  372.   UpdateWindow(hWnd);
  373. }
  374.  
  375.  
  376. /*--------------------------------------------------------------+ 
  377. | fileOpenMovie - open an AVI movie. Use CommDlg open box to    |
  378. |            open and then handle the initialization to    |
  379. |        show the movie and position it properly.  Keep    |
  380. |        the movie paused when opened.            |
  381. |                                |
  382. |        Sets <fMovieOpened> on success.            |
  383. +--------------------------------------------------------------*/
  384. void fileOpenMovie(HWND hWnd)
  385. {
  386.    OPENFILENAME ofn;
  387.    
  388.    static char szFile [BUFFER_LENGTH];
  389.    static char szFileTitle [BUFFER_LENGTH];
  390.    static int  nLastFilter = 1;      /* keep last file-type opened */
  391.  
  392.    /* use the OpenFile dialog to get the filename */
  393.    memset(&ofn, 0, sizeof(ofn));
  394.    ofn.lStructSize = sizeof(ofn);
  395.    ofn.hwndOwner = hWnd;
  396.    ofn.lpstrFilter = "Video for Windows\0*.avi\0\0";
  397.    ofn.nFilterIndex = nLastFilter;
  398.    ofn.lpstrFile = szFile;
  399.    ofn.nMaxFile = sizeof(szFile);
  400.    ofn.lpstrFileTitle = szFileTitle;
  401.    ofn.nMaxFileTitle = sizeof(szFileTitle);
  402.    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  403.  
  404.    /* use CommDlg to get our filename */
  405.    if (GetOpenFileName(&ofn)){
  406.      char    achCommand[BUFFER_LENGTH];
  407.      DWORD  dw;
  408.  
  409.      /* we got a filename, now close any old movie and open */
  410.      /* the new one.                    */
  411.      if (fMovieOpen)
  412.          fileCloseMovie(hWnd);    
  413.      
  414.      /* we have a .AVI movie to open, use MCI */
  415.      /* 
  416.      | build up the string -
  417.      |      open alias mov parent HWND FILENAME
  418.      | to pass to mciSendString 
  419.      */
  420.     wsprintf((LPSTR)achCommand,"open %s alias mov style child parent %d",
  421.              ofn.lpstrFile,hWnd);
  422.  
  423.      /* try to open the file */
  424.      if (mciSendString((LPSTR)achCommand, NULL, 0, NULL) == 0){
  425.  
  426.          fMovieOpen = TRUE;
  427.  
  428.          /* we opened the file o.k., now set up to */
  429.          /* play it.                   */
  430.          mciSendString("window mov state show", NULL, 0, NULL);
  431.          /* get the window handle */
  432.          if ((dw = mciSendString("status mov window handle", 
  433.             (LPSTR)achCommand, sizeof(achCommand), 
  434.             NULL)) == 0L)
  435.             hwndMovie = (HWND)atoi(achCommand);
  436.          else {
  437.              mciGetErrorString(dw, achCommand, 
  438.                      sizeof(achCommand));
  439.              MessageBox(hWnd, achCommand, NULL,
  440.                  MB_ICONEXCLAMATION|MB_OK);
  441.          }
  442.          /* now get the movie centered */
  443.          positionMovie(hWnd);
  444.      } else {
  445.          /* generic error for open */
  446.          MessageBox(hWnd, "Unable to open Movie", NULL, 
  447.                   MB_ICONEXCLAMATION|MB_OK);
  448.          fMovieOpen = FALSE;
  449.      }
  450.    }
  451.    /* update menu and title bars */
  452.    if (fMovieOpen)
  453.        titlebarUpdate(hWnd, (LPSTR)ofn.lpstrFileTitle);
  454.    else
  455.        titlebarUpdate(hWnd, NULL);
  456.    menubarUpdate(hWnd);
  457.    
  458.    
  459.    /* cause an update to occur */
  460.    InvalidateRect(hWnd, NULL, FALSE);
  461.    UpdateWindow(hWnd);
  462. }
  463.  
  464. /*--------------------------------------------------------------+
  465. | playMovie - play/pause the movie depending on the state    |
  466. |        of the <fPlaying> flag.                |
  467. |                                |
  468. | This function sets the <fPlaying> flag appropriately when done|
  469. |                                |
  470. +--------------------------------------------------------------*/
  471. void playMovie(HWND hWnd, WORD wDirection)
  472. {
  473.    fPlaying = !fPlaying;    /* swap the play flag */
  474.    if (wDirection == NULL)
  475.        fPlaying = FALSE;    /* wDirection == NULL means PAUSE */
  476.  
  477.    /* play/pause the AVI movie */
  478.    if (fPlaying){
  479.        if (wDirection == IDM_RPLAY){
  480.             mciSendString("play mov reverse notify", NULL, 0, hWnd);
  481.        } else {
  482.            mciSendString("play mov notify", NULL, 0, hWnd);
  483.        }
  484.    } else {
  485.        /* tell it to pause */
  486.        mciSendString("pause mov", NULL, 0, NULL);
  487.    }
  488. }
  489.  
  490. /*--------------------------------------------------------------+
  491. | seekMovie - seek in the movie depending on the wAction.    |
  492. |          Possible actions are IDM_HOME (start of movie) or    |
  493. |          IDM_END (end of movie)                |
  494. |                                |
  495. |          Always stop the play before seeking.        |
  496. |                                |
  497. +--------------------------------------------------------------*/
  498. void seekMovie(HWND hWnd, WORD wAction)
  499. {
  500.    /* first stop the movie from playing if it is playing */
  501.    if (fPlaying){
  502.        playMovie(hWnd, NULL);    
  503.    }
  504.    if (wAction == IDM_HOME){
  505.        /* home the movie */
  506.            mciSendString("seek mov to start", NULL, 0, NULL);
  507.             
  508.    } else if (wAction == IDM_END){
  509.        /* go to the end of the movie */
  510.            mciSendString("seek mov to end", NULL, 0, NULL);
  511.    } 
  512. }
  513.  
  514. /*--------------------------------------------------------------+
  515. | stepMovie - step forward or reverse in the movie.  wDirection    |
  516. |        can be IDM_STEP (forward) or IDM_RSTEP (reverse)|
  517. |                                |
  518. |        Again, stop the play if one is in progress.    |
  519. |                                |
  520. +--------------------------------------------------------------*/
  521. void stepMovie(HWND hWnd, WORD wDirection)
  522. {
  523.    if (fPlaying)
  524.        playMovie(hWnd, NULL);  /* turn off the movie */
  525.        
  526.    if (wDirection == IDM_STEP)
  527.        mciSendString("step mov by 1", NULL, 0, NULL);
  528.    else
  529.        mciSendString("step mov reverse by 1", NULL,0, NULL);
  530. }
  531.  
  532. /*--------------------------- end of file ----------------------*/
  533.